package com.yc.testupload.controller;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.yc.testupload.HighlightedCodeWordGenerator;

@WebServlet(name = "documentSaveServlet", value = "/api/save-document")
public class DocumentSaveServlet extends HttpServlet {

    private static final Logger logger = LogManager.getLogger(DocumentSaveServlet.class);
    // 文档保存目录
    private static final String DOCUMENT_DIR = "generated_documents";

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        logger.info("[文档保存] 收到保存文档请求");

        // 设置响应类型
        response.setContentType("application/json;charset=utf-8");
        response.setCharacterEncoding("UTF-8");

        try {
            // 获取请求参数
            String content = request.getParameter("content");
            String fileName = request.getParameter("fileName");

            // 添加日志记录，便于追踪调用来源
            logger.info("接收到文档保存请求，来源IP: {}", request.getRemoteAddr());
            logger.info("请求参数 - content: {}, fileName: {}", content, fileName);

            if (content == null || content.trim().isEmpty()) {
                logger.warn("文档内容为空，来自IP: {}", request.getRemoteAddr());
                response.getWriter().write("{\"success\": false, \"message\": \"文档内容不能为空，请确保传递了非空的content参数\"}");
                return;
            }

            // 如果没有提供文件名，生成一个默认文件名
            if (fileName == null || fileName.trim().isEmpty()) {
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmmss");
                fileName = "面试题文档_" + dateFormat.format(new Date()) + ".doc";
            } else if (!fileName.toLowerCase().endsWith(".doc")) {
                fileName += ".doc";
            }

            // 确保保存目录存在
            File directory = new File(DOCUMENT_DIR);
            boolean directoryCreated = false;
            if (!directory.exists()) {
                // 尝试创建目录
                directoryCreated = directory.mkdirs();
                logger.info("[文档保存] 尝试创建文档保存目录: {}, 创建结果: {}", DOCUMENT_DIR, directoryCreated);

                // 再次检查目录是否存在，确保创建成功
                if (!directory.exists()) {
                    logger.error("[文档保存] 创建文档保存目录失败: {}, 即使mkdirs()返回: {}", DOCUMENT_DIR, directoryCreated);
                    response.getWriter().write("{\"success\": false, \"message\": \"创建文档保存目录失败\"}");
                    return;
                }
            }
            logger.info("[文档保存] 文档保存目录已确认存在: {}", directory.getAbsolutePath());

            // 保存文件
            String filePath = DOCUMENT_DIR + File.separator + fileName;
            try {
                // 再次验证目录是否存在，确保在文件写入前目录可用
                File parentDir = new File(filePath).getParentFile();
                if (!parentDir.exists() || !parentDir.isDirectory()) {
                    logger.error("[文档保存] 文件保存路径的父目录不存在或不是目录: {}", parentDir.getAbsolutePath());
                    response.getWriter().write("{\"success\": false, \"message\": \"文件保存路径的目录不存在\"}");
                    return;
                }

                // 使用新的代码高亮Word生成器
                HighlightedCodeWordGenerator generator = new HighlightedCodeWordGenerator();
                generator.generateWordWithCodeHighlighting(
                        fileName.replace(".doc", ""), content, filePath);

                // 验证文件是否成功保存
                File savedFile = new File(filePath);
                if (savedFile.exists() && savedFile.isFile() && savedFile.length() > 0) {
                    logger.info("[文档保存] 带有代码高亮的Word文档成功保存并验证通过: {}, 文件大小: {}字节",
                            filePath, savedFile.length());

                    // 正确生成JSON响应，使用预定义的JSON字符串模板
                    String jsonResponse = "{\"success\": true, \"message\": \"文档已保存到项目目录\", \"filePath\": \""
                            + filePath.replace("\\", "\\\\") + "\"}";

                    response.getWriter().write(jsonResponse);
                } else {
                    String errorDetails = String.format("文件验证失败 - 路径: %s, 存在: %s, 是文件: %s, 文件大小: %s字节",
                            filePath, savedFile.exists(), savedFile.isFile(),
                            savedFile.exists() ? savedFile.length() : "N/A");
                    logger.error("[文档保存] 文件保存到本地失败或文件为空: {}", errorDetails);
                    response.getWriter().write("{\"success\": false, \"message\": \"文件保存失败，请重试\"}");
                }
            } catch (IOException e) {
                logger.error("[文档保存] 保存文件时出错: {}, 详细信息: ", e.getMessage(), e);
                // 正确生成错误JSON响应
                String errorMessage = "保存文件失败: " + e.getMessage();
                // 转义错误消息中的特殊字符
                errorMessage = errorMessage.replace("\\", "\\\\").replace("\"", "\\\"");
                String jsonResponse = "{\"success\": false, \"message\": \"" + errorMessage + "\"}";

                response.getWriter().write(jsonResponse);
            }

        } catch (Exception e) {
            logger.error("[文档保存] 处理请求时出错: {}", e.getMessage());
            response.getWriter().write("{\"success\": false, \"message\": \"处理请求失败: " + e.getMessage() + "\"}");
        }
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }

    /**
     * 生成带有代码语法高亮支持的HTML内容（备用方法）
     * 现在主要使用HighlightedCodeWordGenerator直接生成Word文档
     */
    private String generateHtmlWithCodeHighlighting(String title, String content) {
        StringBuilder htmlBuilder = new StringBuilder();

        // 基础HTML文档结构
        htmlBuilder.append("<!DOCTYPE html>\n");
        htmlBuilder.append("<html>\n");
        htmlBuilder.append("<head>\n");
        htmlBuilder.append("    <meta charset=\"UTF-8\">\n");
        htmlBuilder.append("    <title>").append(escapeHtml(title)).append("</title>\n");
        htmlBuilder.append("    <style>\n");
        htmlBuilder.append("        /* 代码高亮样式 */\n");
        htmlBuilder.append("        .highlight .keyword { color: #708; }        /* 关键字 */\n");
        htmlBuilder.append("        .highlight .string { color: #a31515; }       /* 字符串 */\n");
        htmlBuilder.append("        .highlight .comment { color: #008000; }      /* 注释 */\n");
        htmlBuilder.append("        .highlight .number { color: #098658; }       /* 数字 */\n");
        htmlBuilder.append("        .highlight .operator { color: #0000ff; }     /* 操作符 */\n");
        htmlBuilder.append("        .highlight .punctuation { color: #000000; }  /* 标点符号 */\n");
        htmlBuilder.append("        \n");
        htmlBuilder.append("        body {\n");
        htmlBuilder.append("            font-family: 'Microsoft YaHei', Arial, sans-serif;\n");
        htmlBuilder.append("            line-height: 1.6;\n");
        htmlBuilder.append("            margin: 20px;\n");
        htmlBuilder.append("        }\n");
        htmlBuilder.append("        h1 {\n");
        htmlBuilder.append("            text-align: center;\n");
        htmlBuilder.append("            color: #333;\n");
        htmlBuilder.append("            margin-bottom: 30px;\n");
        htmlBuilder.append("            font-size: 20pt;\n");
        htmlBuilder.append("            font-weight: bold;\n");
        htmlBuilder.append("        }\n");
        htmlBuilder.append("        p {\n");
        htmlBuilder.append("            margin: 10px 0;\n");
        htmlBuilder.append("            text-indent: 2em;\n");
        htmlBuilder.append("        }\n");
        htmlBuilder.append("        pre {\n");
        htmlBuilder.append("            background-color: #f5f5f5;\n");
        htmlBuilder.append("            border: 1px solid #ddd;\n");
        htmlBuilder.append("            padding: 15px;\n");
        htmlBuilder.append("            border-radius: 4px;\n");
        htmlBuilder.append("            overflow-x: auto;\n");
        htmlBuilder.append("            font-family: 'Courier New', monospace;\n");
        htmlBuilder.append("            white-space: pre-wrap;\n");
        htmlBuilder.append("            margin: 15px 0;\n");
        htmlBuilder.append("        }\n");
        htmlBuilder.append("        code {\n");
        htmlBuilder.append("            font-family: 'Courier New', monospace;\n");
        htmlBuilder.append("            background-color: #f5f5f5;\n");
        htmlBuilder.append("            padding: 2px 4px;\n");
        htmlBuilder.append("            border-radius: 3px;\n");
        htmlBuilder.append("            font-size: 10pt;\n");
        htmlBuilder.append("        }\n");
        htmlBuilder.append("        .question {\n");
        htmlBuilder.append("            font-weight: bold;\n");
        htmlBuilder.append("            color: #2c3e50;\n");
        htmlBuilder.append("            margin-top: 20px;\n");
        htmlBuilder.append("        }\n");
        htmlBuilder.append("        .answer {\n");
        htmlBuilder.append("            color: #34495e;\n");
        htmlBuilder.append("            margin-left: 20px;\n");
        htmlBuilder.append("        }\n");
        htmlBuilder.append("    </style>\n");
        htmlBuilder.append("</head>\n");
        htmlBuilder.append("<body>\n");
        htmlBuilder.append("    <h1>").append(escapeHtml(title)).append("</h1>\n");

        // 处理内容，识别并格式化代码块
        // 1. 识别并处理行内代码（`code` 格式）
        content = content.replaceAll("`([^`]+)`", "<code>$1</code>");

        // 2. 识别并处理多行代码块（```code``` 格式）
        java.util.regex.Pattern codeBlockPattern = java.util.regex.Pattern.compile("```([\\s\\S]*?)```");
        java.util.regex.Matcher matcher = codeBlockPattern.matcher(content);
        int lastIndex = 0;
        StringBuilder processedContentBuilder = new StringBuilder();

        while (matcher.find()) {
            // 添加代码块之前的内容
            if (matcher.start() > lastIndex) {
                processedContentBuilder.append(escapeHtml(
                        content.substring(lastIndex, matcher.start())));
            }
            // 添加格式化的代码块
            processedContentBuilder.append("<pre class=\"highlight\">")
                    .append(escapeHtml(matcher.group(1)))
                    .append("</pre>");
            lastIndex = matcher.end();
        }

        // 添加剩余内容
        if (lastIndex < content.length()) {
            processedContentBuilder.append(escapeHtml(
                    content.substring(lastIndex)));
        }

        // 为面试题添加特殊格式
        String[] lines = processedContentBuilder.toString().split("\\n");
        for (String line : lines) {
            line = line.trim();
            if (line.startsWith("问题") ||
                    line.matches("^\\d+\\.\\s*问题") ||
                    line.matches("^\\d+\\.\\s*题目") ||
                    line.matches("^问题\\d+：")) {
                htmlBuilder.append("    <div class=\"question\">")
                        .append(line)
                        .append("</div>\n");
            } else if (line.startsWith("答案") || line.startsWith("解析")) {
                htmlBuilder.append("    <div class=\"answer\">")
                        .append(line)
                        .append("</div>\n");
            } else if (!line.isEmpty()) {
                htmlBuilder.append("    <p>").append(line).append("</p>\n");
            } else {
                htmlBuilder.append("    <br/>\n");
            }
        }

        htmlBuilder.append("</body>\n");
        htmlBuilder.append("</html>");

        return htmlBuilder.toString();
    }

    /**
     * 转义HTML特殊字符
     */
    private String escapeHtml(String text) {
        if (text == null)
            return "";
        return text
                .replace("&", "&amp;")
                .replace("<", "&lt;")
                .replace(">", "&gt;")
                .replace("\"", "&quot;")
                .replace("'", "&#39;");
    }
}